﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Data;
using System.Data.SqlClient;
using System.Windows.Forms;
using Lapas.Common.Forms;
using System.Drawing;
using System.Globalization;
using System.Reflection;
using System.ComponentModel;
using System.IO;
using System.Collections;
using System.Linq;

namespace Lapas.Common
{
    public partial class Helper
    {
        #region Color Util
        public static Color Color_Get(string hexCode)
        {
            System.Drawing.ColorConverter colConvert = new ColorConverter();
            return (System.Drawing.Color)colConvert.ConvertFromString(hexCode);
        }
        #endregion

        #region Icons
        public static System.Drawing.Bitmap GetBitmap(string name)
        {
            object obj = Icons.ResourceManager.GetObject(name, Icons.Culture);
            return ((System.Drawing.Bitmap)(obj));
        }
        public static System.Drawing.Icon GetIcon(string name)
        {
            object obj = Icons.ResourceManager.GetObject(name, Icons.Culture);
            return ((System.Drawing.Icon)(obj));
        }
        #endregion

        #region Globalziation
        
        static System.Resources.ResourceManager resourceManager = 
            new System.Resources.ResourceManager("Lapas.CommonResource", System.Reflection.Assembly.GetExecutingAssembly());
        protected static string GetLocalizeString(string input, System.Resources.ResourceManager resourceManager)
        {
            return GetLocalizeString(input, resourceManager, System.Globalization.CultureInfo.CurrentCulture);
        }

        public static string GetLocalizeString(string input, System.Resources.ResourceManager resourceManager, System.Globalization.CultureInfo cultureInfor)
        {
            string resource = resourceManager.GetString(input, cultureInfor);
            if (string.IsNullOrEmpty(resource))
                resource = input;

            return resource;
        }

        public static string GetLocalizeString(string input)
        {
            try
            {
                return GetLocalizeString(input, resourceManager);
            }
            catch
            {
                return input;
            }
        }
        #endregion
       
           
        //public static OExcelDocument DSSoHuuCKLuuKy_SaiGon
        //{
        //    get { return GetDocument("OExcel.Components.Template.DSSoHuuCK.DSSoHuuCKLuuKy_SaiGon.xml"); }
        //}

        #region Sql util
        public static string SqlFormatText(string text)
        {
            if (text == null) return "";
            else return text.Replace("'", "''");
        }
        public static string SqlDeFormatText(string text)
        {
            if (text == null) return "";
            else return text.Replace("''", "'");
        }
        #endregion

        public static bool IsInt(string text)
        {
            try
            {
                int i = Int32.Parse(text); return true;
            }
            catch { return false; }
        }

        public static bool IsInt(string text, System.Globalization.NumberFormatInfo numberFormatInfo, out int i)
        {
            return int.TryParse(text, System.Globalization.NumberStyles.Any, numberFormatInfo, out i);
        }


        public static bool IsDecimal(string text)
        {
            try
            {
                decimal i = Decimal.Parse(text); return true;
            }
            catch { return false; }
        }


        public static bool IsDecimal(string text, System.Globalization.NumberFormatInfo numberFormatInfo, out decimal d)
        {
            return decimal.TryParse(text, System.Globalization.NumberStyles.Number, numberFormatInfo, out d);
        }

        public static string ConvertNumberToString(string number)
        {
            if (number.Contains(".")) return "";
            if (number[0].ToString() == "-")
            {
                number = number.Substring(1, number.Length - 1);
            }
            string[] so = new string[10];
            so[0] = "không";
            so[1] = "một";
            so[2] = "hai";
            so[3] = "ba";
            so[4] = "bốn";
            so[5] = "năm";
            so[6] = "sáu";
            so[7] = "bảy";
            so[8] = "tám";
            so[9] = "chín";
            string[] hang = new string[4];
            hang[0] = "";
            hang[1] = "nghìn";
            hang[2] = "triệu";
            hang[3] = "tỷ";

            int i = 0, j = 0, donvi = 0, chuc = 0, tram = 0;
            string str = "";
            string a, b;
            i = number.Length - 1;
            if (i == 0)
            {
                str = so[Convert.ToInt32(number)];//so[0] + str;Sua loi convert hang don vi
            }
            else
            {
                j = 0;
                while (i >= 0)
                {
                    donvi = Convert.ToInt32(number.Substring(i, 1));
                    i = i - 1;
                    if (i >= 0)
                    {
                        chuc = Convert.ToInt32(number.Substring(i, 1));
                    }
                    else
                    {
                        chuc = -1;
                    }
                    i = i - 1;
                    if (i >= 0)
                    {
                        tram = Convert.ToInt32(number.Substring(i, 1));
                    }
                    else
                    {
                        tram = -1;
                    }
                    i = i - 1;
                    if (donvi > 0 || chuc > 0 || tram > 0 || j == 3)
                    {
                        str = hang[j] + " " + str;
                    }
                    j = j + 1;
                    if (j > 3)
                    {
                        j = 1;
                    }
                    if (donvi < 0)
                    {
                        break;
                    }
                    else
                    {
                        if (donvi == 5 && chuc > 0)
                        {
                            str = "lăm " + str;
                        }
                        else
                        {

                            if (donvi == 4 && chuc > 0)
                            {
                                if (donvi == 4 && chuc == 1)
                                {
                                    str = "bốn " + str;
                                }
                                else
                                {
                                    str = "tư " + str;
                                }
                            }
                            else
                            {
                                if (donvi == 1 && chuc > 1)
                                {
                                    str = "mốt " + str;
                                }
                                else
                                {
                                    if (donvi == 1 && chuc == 1)
                                    {
                                        str = "một " + str;
                                    }
                                    else
                                    {
                                        if (donvi > 0)
                                        {
                                            str = so[donvi] + " " + str;
                                        }
                                    }
                                }
                            }
                        }
                    }// Donvi < 0
                    if (chuc < 0)
                    {
                        break;
                    }
                    else
                    {
                        if (chuc == 0 && donvi > 0)
                        {
                            str = "linh " + str;
                        }
                        else
                        {
                            if (chuc == 1)
                            {
                                str = "mười " + str;
                            }
                            else
                            {
                                if (chuc > 1)
                                {
                                    str = so[chuc] + " mươi " + str;
                                }
                            }
                        }
                    }// Chuc < 0
                    if (tram < 0)
                    {
                        break;
                    }
                    else
                    {
                        if (tram > 0 || chuc > 0 || donvi > 0)
                        {
                            str = so[tram] + " trăm " + str;
                        }
                    }

                }
            }
            str = str.Trim();
            a = str.Substring(0, 1);
            b = str.Substring(1, str.Length - 1);
            a = a.ToUpper();
            str = a + b;
            return str;
        }

        /// <summary>
        /// Xác định quí của ngày date
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public static int GetQuaterOf(DateTime date)
        {
            int month = date.Month;
            if ((1 <= month) && (month <= 3)) { return 1; }
            else if ((4 <= month) && (month <= 6)) { return 2; }
            else if ((7 <= month) && (month <= 9)) { return 3; }
            else return 4;
        }

        /// <summary>
        /// Xác định ngày cuối quí trước
        /// </summary>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public static DateTime GetPreviousQuaterOf(DateTime endDate)
        {
            int currentQuater = GetQuaterOf(endDate);
            switch (currentQuater)
            {
                case 1: return new DateTime(endDate.Year - 1, 12, 31);
                case 2: return new DateTime(endDate.Year, 3, 31);
                case 3: return new DateTime(endDate.Year, 6, 30);
                default: return new DateTime(endDate.Year, 9, 30);
            }
        }


        public static string DateTime_GetString(DateTime date)
        {
            return date.ToString("dd/MM/yyyy");
        }
        public static DateTime DateTime_FromString(string dateTimeString)
        {
            IFormatProvider culture = new CultureInfo("fr-FR", true);
            return DateTime_FromString(dateTimeString, culture);
        }
        public static DateTime DateTime_FromString(string dateTimeString, IFormatProvider culture)
        {
            DateTime dateTime =
                DateTime.Parse(dateTimeString,
                               culture,
                               DateTimeStyles.NoCurrentDateDefault);
            return dateTime;
        }

        #region Globalziation param
        public const string GiaoDichKhachHang_HopDongMuaTienBanChungKhoan_BuyCastContractListForm_Resource = "Lapas.GiaoDichKhachHangModule.HopDongMuaTienBanChungKhoanModule.BuyCastContract_Resource";
        public const string KiemSoatModule_DanhSachTaiKhoan_DanhSachTaiKhoanNoiBang_BalanceObjectResource = "Lapas.KiemSoatModule.DanhSachTaiKhoan.DanhSachTaiKhoanNoiBang.BalanceObjectResource";
        public const string KiemSoatModule_DanhSachTaiKhoan_DanhSachTaiKhoanNoiBang_BalanceObjectEditResource = "Lapas.KiemSoatModule.DanhSachTaiKhoan.DanhSachTaiKhoanNoiBang.BalanceObjectEditResource";
        public const string GiaoDichKhachHang_CamCo_MortageContractListForm_Resource = "Lapas.GiaoDichKhachHangModule.MortageModule.MortageModule_Resource";
        public const string KiemSoatModule_BieuPhi_TiLeKiQuiResource = "Lapas.KiemSoatModule.BieuPhi.TiLeKiQui.TiLeKiQuiResource";
        public const string QuanLyBieuPhiMoiGioi_Resource = "Lapas.KiemSoatModule.BieuPhi.GiaoDichMoiGioi.TradeFeeResource";
        public const string GiaoDichKeToanModule_GiaoDichNoiBang_VAT_Resource = "Lapas.GiaoDichKeToanModule.GiaoDichNoiBang.VAT.VatResources";
        public const string MasterDataModule_Accountant_GLRateModule_GLRateResource = "Lapas.MasterDataModule.Accountant.GLRateModule.GLRateResource";
        #endregion

        /// <summary>
        /// Khai bao Parameter output kieu decimal
        /// </summary>
        /// <param name="parameterName">Ten bien</param>
        /// <param name="precision">Do dai</param>
        /// <param name="scale">Do dai sau dau phay</param>
        /// <returns></returns>
        public static SqlParameter DelareDecimalParameter(string parameterName, byte precision, byte scale)
        {
            SqlParameter parameter = new SqlParameter(parameterName, SqlDbType.Decimal);
            parameter.Precision = precision;
            parameter.Scale = scale;
            parameter.Direction = ParameterDirection.Output;
            return parameter;
        }

        /// <summary>
        /// Chuyển từ có dấu sang không dấu
        /// 20070817 TriDM: chuyen tu CustomerEdit sang
        /// 20071222 TriDM: cai tien ko su dung toUpper()
        /// 20080115 TriDM: update vao Lapas
        /// 20080123 TriDM: chuyen lai nhu cu, dang UpperCase
        /// </summary>
        /// <param name="inputStr"></param>
        /// <returns></returns>
        public static string ChangeString(string inputStr)
        {
            StringBuilder sb = new StringBuilder(inputStr.ToUpper());
            //Thay doi cac nguyen am tieng viet

            #region Replace Upper
            sb.Replace("Á", "A");
            sb.Replace("À", "A");
            sb.Replace("Ả", "A");
            sb.Replace("Ạ", "A");
            sb.Replace("Ã", "A");

            sb.Replace("Â", "A");
            sb.Replace("Ấ", "A");
            sb.Replace("Ầ", "A");
            sb.Replace("Ẩ", "A");
            sb.Replace("Ậ", "A");
            sb.Replace("Ẫ", "A");

            sb.Replace("Ă", "A");
            sb.Replace("Ắ", "A");
            sb.Replace("Ằ", "A");
            sb.Replace("Ẳ", "A");
            sb.Replace("Ặ", "A");
            sb.Replace("Ẵ", "A");

            sb.Replace("Ò", "O");
            sb.Replace("Ó", "O");
            sb.Replace("Ỏ", "O");
            sb.Replace("Ọ", "O");
            sb.Replace("Õ", "O");

            sb.Replace("Ô", "O");
            sb.Replace("Ố", "O");
            sb.Replace("Ồ", "O");
            sb.Replace("Ổ", "O");
            sb.Replace("Ộ", "O");
            sb.Replace("Ỗ", "O");

            sb.Replace("Ơ", "O");
            sb.Replace("Ờ", "O");
            sb.Replace("Ớ", "O");
            sb.Replace("Ở", "O");
            sb.Replace("Ợ", "O");
            sb.Replace("Ỡ", "O");

            sb.Replace("É", "E");
            sb.Replace("È", "E");
            sb.Replace("Ẻ", "E");
            sb.Replace("Ẹ", "E");
            sb.Replace("Ẽ", "E");

            sb.Replace("Ê", "E");
            sb.Replace("Ế", "E");
            sb.Replace("Ề", "E");
            sb.Replace("Ể", "E");
            sb.Replace("Ệ", "E");
            sb.Replace("Ễ", "E");

            sb.Replace("Ú", "U");
            sb.Replace("Ù", "U");
            sb.Replace("Ủ", "U");
            sb.Replace("Ụ", "U");
            sb.Replace("Ũ", "U");

            sb.Replace("Ư", "U");
            sb.Replace("Ú", "U");
            sb.Replace("Ừ", "U");
            sb.Replace("Ứ", "U");
            sb.Replace("Ử", "U");
            sb.Replace("Ự", "U");
            sb.Replace("Ữ", "U");

            sb.Replace("Í", "I");
            sb.Replace("Ì", "I");
            sb.Replace("Ỉ", "I");
            sb.Replace("Ị", "I");
            sb.Replace("Ĩ", "I");

            sb.Replace("Ý", "Y");
            sb.Replace("Ỳ", "Y");
            sb.Replace("Ỷ", "Y");
            sb.Replace("Ỵ", "Y");
            sb.Replace("Ỹ", "Y");

            sb.Replace("Đ", "D");
            #endregion

            //#region Replace lower
            //sb.Replace("á", "a");
            //sb.Replace("à", "a");
            //sb.Replace("ả", "a");
            //sb.Replace("ạ", "a");
            //sb.Replace("ã", "a");

            //sb.Replace("â", "a");
            //sb.Replace("ầ", "a");
            //sb.Replace("ấ", "a");
            //sb.Replace("ẩ", "a");
            //sb.Replace("ẫ", "a");
            //sb.Replace("ậ", "a");

            //sb.Replace("ă", "a");
            //sb.Replace("ằ", "a");
            //sb.Replace("ắ", "a");
            //sb.Replace("ẳ", "a");
            //sb.Replace("ẵ", "a");
            //sb.Replace("ặ", "a");

            //sb.Replace("ò", "o");
            //sb.Replace("ó", "o");
            //sb.Replace("ỏ", "o");
            //sb.Replace("õ", "o");
            //sb.Replace("ọ", "o");

            //sb.Replace("ô", "o");
            //sb.Replace("ồ", "o");
            //sb.Replace("ố", "o");
            //sb.Replace("ổ", "o");
            //sb.Replace("ỗ", "o");
            //sb.Replace("ộ", "o");

            //sb.Replace("ơ", "o");
            //sb.Replace("ờ", "o");
            //sb.Replace("ớ", "o");
            //sb.Replace("ở", "o");
            //sb.Replace("ỡ", "o");
            //sb.Replace("ợ", "o");

            //sb.Replace("è", "e");
            //sb.Replace("é", "e");
            //sb.Replace("ẻ", "e");
            //sb.Replace("ẽ", "e");
            //sb.Replace("ẹ", "e");

            //sb.Replace("ê", "e");
            //sb.Replace("ề", "e");
            //sb.Replace("ế", "e");
            //sb.Replace("ể", "e");
            //sb.Replace("ễ", "e");
            //sb.Replace("ệ", "e");

            //sb.Replace("ù", "u");
            //sb.Replace("ú", "u");
            //sb.Replace("ủ", "u");
            //sb.Replace("ũ", "u");
            //sb.Replace("ụ", "u");

            //sb.Replace("ư", "u");
            //sb.Replace("ừ", "u");
            //sb.Replace("ứ", "u");
            //sb.Replace("ử", "u");
            //sb.Replace("ữ", "u");
            //sb.Replace("ự", "u");


            //sb.Replace("ì", "i");
            //sb.Replace("í", "i");
            //sb.Replace("ỉ", "i");
            //sb.Replace("ĩ", "i");
            //sb.Replace("ị", "i");

            //sb.Replace("ỳ", "y");
            //sb.Replace("ý", "y");
            //sb.Replace("ỷ", "y");
            //sb.Replace("ỹ", "y");
            //sb.Replace("ỵ", "y");

            //sb.Replace("đ", "d");

            //#endregion

            return sb.ToString();
        }

        /// <summary>
        /// Extract object's property to XML 
        /// </summary>
        /// <param name="source">Source Object</param>
        /// <returns>xml string</returns>
        public static string obj2XML(object source)
        {
            return obj2XML(source, new List<string>());
        }

        public static string obj2XML(object source, List<string> exceptList)
        {
            if (source == null)
            {//20090911 Haids: update trường hợp null
                return null;
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                string objName = source.GetType().Name;
                sb.Append("<" + objName + ">");
                List<PropertyInfo> props = GetTargetProperties(source.GetType());
                foreach (PropertyInfo item in props)
                {
                    string propName = item.Name;
                    
                    if (exceptList.Any(e=>e==propName)) continue;

                    object value = item.GetValue(source, null);
                    if (value != null)
                        if (value.ToString().Trim().Length > 0)
                            sb.Append(string.Format("<{0}>{1}</{0}>", propName, value.ToString().Trim()));
                }
                sb.Append("</" + objName + ">");
                return sb.ToString();
            }
        }

        /// <summary>
        /// Extract object's property to string 
        /// </summary>
        /// <param name="source">Source Object</param>
        /// <returns>result string</returns>
        public static string ObjectToString(object source)
        {
            StringBuilder sb = new StringBuilder();

            List<PropertyInfo> props = GetTargetProperties(source.GetType());
            foreach (PropertyInfo item in props)
            {
                string propName = item.Name;
                object value = item.GetValue(source, null);
                if (value != null)
                {
                    if (value.ToString().Trim().Length > 0)
                    {
                        sb.Append(string.Format(CultureInfo.InvariantCulture, "{0}={1}; ", propName, value.ToString().Trim()));
                    }
                    else
                    {
                        sb.Append(string.Format(CultureInfo.InvariantCulture, "{0}=NULL; ", propName));
                    }
                }
                else
                {
                    sb.Append(string.Format(CultureInfo.InvariantCulture, "{0}=NULL; ", propName));
                }
            }

            return sb.ToString();
        }

        /// <summary>
        /// Get list properties of an object
        /// </summary>
        /// <param name="targetType">Type of object</param>
        /// <returns>List</returns>
        public static List<PropertyInfo> GetTargetProperties(Type targetType)
        {
            List<PropertyInfo> result = new List<PropertyInfo>();
            PropertyDescriptorCollection props =
              TypeDescriptor.GetProperties(targetType);
            foreach (PropertyDescriptor item in props)
                if (item.IsBrowsable)
                    result.Add(targetType.GetProperty(item.Name));
            return result;
        }



        /// <summary>
        /// Sets an object's property with the specified value,
        /// coercing that value to the appropriate type if possible.
        /// </summary>
        /// <param name="target">Object containing the property to set.</param>
        /// <param name="propertyName">Name of the property to set.</param>
        /// <param name="value">Value to set into the property.</param>
        public static void SetPropertyValue(
          object target, string propertyName, object value)
        {
            PropertyInfo propertyInfo =
              target.GetType().GetProperty(propertyName);
            if (value == null)
                propertyInfo.SetValue(target, value, null);
            else
            {
                Type pType =
                  Utilities.GetPropertyType(propertyInfo.PropertyType);
                Type vType =
                  Utilities.GetPropertyType(value.GetType());
                if (pType.Equals(vType))
                {
                    // types match, just copy value
                    propertyInfo.SetValue(target, value, null);
                }
                else
                {
                    // types don't match, try to coerce
                    if (pType.Equals(typeof(Guid)))
                        propertyInfo.SetValue(
                          target, new Guid(value.ToString()), null);
                    else if (pType.IsEnum && vType.Equals(typeof(string)))
                        propertyInfo.SetValue(target, Enum.Parse(pType, value.ToString()), null);
                    else
                        propertyInfo.SetValue(
                          target, Convert.ChangeType(value, pType), null);
                }
            }
        }
        public static void File_CreateText(string text)
        {
            using (StreamWriter sw = new StreamWriter(string.Format(Application.StartupPath + @"\Lapas.{0}.log", DateTime.Now.ToString("yyyyMMdd.HHmm"))))
            {
                sw.Write(text);
                sw.Flush();
                sw.Close();
            }
        }

        public static readonly string LanguageCodeVi = "vi-VN";
        public static readonly string LanguageCodeEn = "en-US";

        /// <summary>
        /// Kiểm soát giá trị DateTime có nằm trong khoảng hay không?
        /// 20090420 TriDM
        /// </summary>
        /// <param name="dateTime"></param>
        public static void ValidateDateTime(DateTime dateTime)
        {
            if (dateTime < new DateTime(1900, 01, 01))
            {
                throw new Exception("Ngày nhỏ hơn 01-01-1900 không hợp lệ");
            }

            if (dateTime > new DateTime(2079, 01, 01))
            {
                throw new Exception("Ngày lớn hơn 01-01-2079 không hợp lệ");
            }
        }

        public static void SetTabPageEnable(TabPage tabPage, bool enable)
        {
            foreach (Control control in tabPage.Controls)
            {
                control.Enabled = enable;
            }
        }
    }


    /// <summary>
    /// Bắt các lỗi thuộc về đặt lệnh
    /// </summary>
    [Serializable()]
    public class LapasException : Exception
    {

        private SbsExErrorCode errCode;

        public SbsExErrorCode ErrorCode
        {
            get { return errCode; }
            set { errCode = value; }
        }

        /// <summary>
        /// Hàm khởi tạo
        /// </summary>
        public LapasException()
        {

        }

        /// <summary>
        /// Hàm khởi tạo với tham số là messge lỗi
        /// </summary>
        /// <param name="message">Thông báo lỗi</param>
        public LapasException(string message)
            : base(message)
        {

        }

        /// <summary>
        /// Lỗi kèm theo ErrorCode
        /// </summary>
        /// <param name="errorCode"></param>
        /// <param name="message"></param>
        public LapasException(SbsExErrorCode errorCode, string message)
            : base(message)
        {
            ErrorCode = errorCode;
        }

        /// <summary>
        /// Hàm khởi tạo lớp
        /// Với thông báo lỗi và tham chiếu đến nơi phát sinh ra lỗi        
        /// </summary>

        public LapasException(string message, Exception innerException)
            : base(message, innerException)
        {

        }

        /// <summary>
        /// Initializes a new instance of the 
        /// PorscheGateway.LapasException" class
        /// with serialized data.
        /// </summary>
        protected LapasException(System.Runtime.Serialization.SerializationInfo info,
            System.Runtime.Serialization.StreamingContext context)
            : base(info, context)
        {

        }
    }


    /// <summary>
    /// 
    /// </summary>
    [Serializable()]
    public class SbsUIException : LapasException
    {
        #region constructor
        /// <summary>
        /// 
        /// </summary>
        public SbsUIException()
        { }
        /// <summary>
        /// Hàm khởi tạo với tham số là messge lỗi
        /// </summary>
        /// <param name="message">Thông báo lỗi</param>
        public SbsUIException(string message)
            : base(message)
        {

        }

        /// <summary>
        /// Hàm khởi tạo lớp
        /// Với thông báo lỗi và tham chiếu đến nơi phát sinh ra lỗi        
        /// </summary>
        public SbsUIException(string message, Exception innerException)
            : base(message, innerException)
        {

        }

        /// <summary>
        /// Initializes a new instance of the 
        /// PorscheGateway.SBSException" class
        /// with serialized data.
        /// </summary>
        protected SbsUIException(System.Runtime.Serialization.SerializationInfo info,
            System.Runtime.Serialization.StreamingContext context)
            : base(info, context)
        {

        }
        #endregion

        #region Properties
        /// <summary>
        /// 
        /// </summary>
        public System.Windows.Forms.Control UIControl { get; set; }
        #endregion

        //#region ISerializable Members

        //[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
        //public void GetObjectData(SerializationInfo info, StreamingContext context)
        //{
        //    //if (info == null)
        //    //    throw new ArgumentNullException("info");

        //    //info.AddValue("Text", _Text);
        //}


        //#endregion
    }


    /// <summary>
    /// 
    /// </summary>
    public sealed class ReflectorHelper
    {
        /// <summary>
        /// 
        /// </summary>
        ReflectorHelper() { }

        #region Reflectors Utilities
        /// <summary>
        /// Extract object's property to XML 
        /// </summary>
        /// <param name="source">Source Object</param>
        /// <returns>xml string</returns>
        public static string Object2Xml(object source)
        {
            StringBuilder sb = new StringBuilder();
            string objName = source.GetType().Name;
            sb.Append("<" + objName + ">");
            List<PropertyInfo> props = GetTargetProperties(source.GetType());
            foreach (PropertyInfo item in props)
            {
                string propName = item.Name;
                object value = item.GetValue(source, null);
                if (value != null)
                    if (value.ToString().Trim().Length > 0)
                        sb.Append(string.Format(CultureInfo.InvariantCulture, "<{0}>{1}</{0}>", propName, value.ToString().Trim()));
            }
            sb.Append("</" + objName + ">");
            return sb.ToString();
        }
        /// <summary>
        /// Get list properties of an object
        /// </summary>
        /// <param name="targetType">Type of object</param>
        /// <returns>List</returns>
        public static List<PropertyInfo> GetTargetProperties(Type targetType)
        {
            List<PropertyInfo> result = new List<PropertyInfo>();
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(targetType);
            foreach (PropertyDescriptor item in props)
                if (item.IsBrowsable)
                    result.Add(targetType.GetProperty(item.Name));
            return result;
        }



        /// <summary>
        /// Sets an object's property with the specified value,
        /// coercing that value to the appropriate type if possible.
        /// </summary>
        /// <param name="target">Object containing the property to set.</param>
        /// <param name="propertyName">Name of the property to set.</param>
        /// <param name="value">Value to set into the property.</param>
        public static void SetPropertyValue(object target, string propertyName, object value)
        {
            if (target == null)
                throw new LapasException(string.Format(CultureInfo.InvariantCulture, SbsExceptionConsts.ObjectNull, target.GetType().Name));
            PropertyInfo propertyInfo = target.GetType().GetProperty(propertyName);
            //Trường hợp không tìm thấy Property
            if (propertyInfo == null)
                return;
            if (value == null)
                propertyInfo.SetValue(target, value, null);
            else
            {
                Type pType = GetPropertyType(propertyInfo.PropertyType);
                Type vType = GetPropertyType(value.GetType());
                if (pType.Equals(vType))
                {
                    // types match, just copy value
                    propertyInfo.SetValue(target, value, null);
                }
                else
                {
                    //if (pType.IsGenericType)
                    //{
                    //    if (pType.GUID.Equals(typeof(Nullable<DateTime>).GUID) && vType.Equals(typeof(DateTime)))
                    //        propertyInfo.SetValue(target, new Nullable<DateTime>((DateTime)value), null);
                    //    else if (pType.GUID.Equals(typeof(Nullable<int>).GUID) && vType.Equals(typeof(int)))
                    //        propertyInfo.SetValue(target, new Nullable<int>((int)value), null);
                    //    else if (pType.GUID.Equals(typeof(Nullable<int>).GUID) && vType.Equals(typeof(bool)))
                    //        propertyInfo.SetValue(target, ((bool)value) ? new Nullable<int>(1) : new Nullable<int>(0), null);
                    //    else if (pType.IsEnum && vType.Equals(typeof(string)))
                    //        propertyInfo.SetValue(target, Enum.Parse(pType, value.ToString()), null);
                    //    else
                    //        propertyInfo.SetValue(target, Convert.ChangeType(value, pType), null);
                    //}
                    //else
                    //{
                        // types don't match, try to coerce
                        if (pType.Equals(typeof(Guid)))
                            propertyInfo.SetValue(target, new Guid(value.ToString()), null);
                        else if (pType.Equals(typeof(DateTime?)) && vType.Equals(typeof(DateTime)))
                            propertyInfo.SetValue(target, value, null);
                        else if (pType.Equals(typeof(int?)) && vType.Equals(typeof(int)))
                            propertyInfo.SetValue(target, value, null);
                        else if ((pType.Equals(typeof(int?)) || pType.Equals(typeof(int))) && vType.Equals(typeof(bool)))
                            propertyInfo.SetValue(target, ((bool)value) ? 1 : 0, null);
                        else if (pType.IsEnum && vType.Equals(typeof(string)))
                            propertyInfo.SetValue(target, Enum.Parse(pType, value.ToString()), null);
                        else
                            propertyInfo.SetValue(target, Convert.ChangeType(value, pType), null);
                    //}
                }
            }
        }
        /// <summary>
        /// Returns a property's value
        /// </summary>
        /// <param name="source"></param>
        /// <param name="propertyName"></param>
        /// <returns></returns>
        public static object GetPropertyValue(object source, string propertyName)
        {
            if (source == null)
                throw new LapasException(string.Format(CultureInfo.InvariantCulture, SbsExceptionConsts.ObjectNull, source.GetType().Name));
            PropertyInfo propertyInfo = source.GetType().GetProperty(propertyName);
            //Trường hợp không tìm thấy Property
            if (propertyInfo == null)
                throw new LapasException(string.Format(CultureInfo.InvariantCulture, SbsExceptionConsts.PropNotFound, propertyName, source.GetType().Name));
            return propertyInfo.GetValue(source, null);
        }

        /// <summary>
        /// Returns a property's type, dealing with
        /// Nullable if necessary.
        /// </summary>
        public static Type GetPropertyType(Type propertyType)
        {
            Type type = propertyType;
            if (type.IsGenericType &&
              (type.GetGenericTypeDefinition() == typeof(Nullable)))
                return type.GetGenericArguments()[0];
            return type;
        }


        #endregion
    }
    
   
}